package org.zhq.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.zhq.enums.OrderStatusEnum;
import org.zhq.enums.YesOrNo;
import org.zhq.mapper.OrderItemsMapper;
import org.zhq.mapper.OrderStatusMapper;
import org.zhq.mapper.OrdersMapper;
import org.zhq.pojo.*;
import org.zhq.pojo.bo.ShopCartBO;
import org.zhq.pojo.bo.SubmitOrderBO;
import org.zhq.pojo.vo.MerchantOrdersVO;
import org.zhq.pojo.vo.OrderVO;
import org.zhq.service.AddressService;
import org.zhq.service.ItemsService;
import org.zhq.service.OrderService;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {

    private final OrdersMapper ordersMapper;

    private final OrderItemsMapper orderItemsMapper;

    private final OrderStatusMapper orderStatusMapper;

    private final AddressService addressService;

    private final ItemsService itemsService;

    @Autowired
    public OrderServiceImpl(OrdersMapper ordersMapper, OrderItemsMapper orderItemsMapper, OrderStatusMapper orderStatusMapper, AddressService addressService, ItemsService itemsService) {
        this.ordersMapper = ordersMapper;
        this.orderItemsMapper = orderItemsMapper;
        this.orderStatusMapper = orderStatusMapper;
        this.addressService = addressService;
        this.itemsService = itemsService;
    }

    /**
     * 用于创建订单相关信息
     *
     * @param shopCartBOList
     * @param submitOrderBO
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public OrderVO createOrder(List<ShopCartBO> shopCartBOList, SubmitOrderBO submitOrderBO) {
        String userId = submitOrderBO.getUserId();
        String addressId = submitOrderBO.getAddressId();
        String itemSpecIds = submitOrderBO.getItemSpecIds();
        Integer payMethod = submitOrderBO.getPayMethod();
        String leftMsg = submitOrderBO.getLeftMsg();
        int postAmount = 0;
        //0.新订单数据保存
        String orderId = IdWorker.getIdStr();
        Orders newOrder = new Orders();
        newOrder.setId(orderId);
        newOrder.setUserId(userId);
        UserAddress userAddress = addressService.queryUserAddress(userId, addressId);
        newOrder.setReceiverName(userAddress.getReceiver());
        newOrder.setReceiverMobile(userAddress.getMobile());
        newOrder.setReceiverAddress(String.format("%s %s %s %s", userAddress.getProvince(), userAddress.getCity(), userAddress.getDistrict(), userAddress.getDetail()));
        newOrder.setPostAmount(postAmount);
        newOrder.setPayMethod(payMethod);
        newOrder.setLeftMsg(leftMsg);
        newOrder.setIsComment(YesOrNo.NO.type);
        newOrder.setIsDelete(YesOrNo.NO.type);
        newOrder.setCreatedTime(new Date());
        newOrder.setUpdatedTime(new Date());
        //1.循环根据ItemSpecIds保存订单商品信息表
        String[] itemSpecArr = itemSpecIds.split(",");
        int totalAmount = 0;
        int realPayAmount = 0;
        List<ItemsSpec> itemsSpecList = itemsService.queryItemSpecListByIds(Arrays.asList(itemSpecArr));
        List<OrderItems> subList = new ArrayList<>();
        List<ShopCartBO> toBeRemoveShopCartList = CollUtil.newArrayList();
        for (ItemsSpec itemsSpec : itemsSpecList) {
            //整合redis后,商品购买的数量重新从redis的购物车中获取
            ShopCartBO shopCartBO = getShopCartBOFromShopCart(shopCartBOList, itemsSpec.getId());
            int buyCounts = shopCartBO.getBuyCounts();
            toBeRemoveShopCartList.add(shopCartBO);
            totalAmount += itemsSpec.getPriceNormal() * buyCounts;
            realPayAmount += itemsSpec.getPriceDiscount() * buyCounts;
            //1.2 根据商品id 获取商品信息以及商品图片
            String itemId = itemsSpec.getItemId();
            Items items = itemsService.queryItemsById(itemId);
            String imgUrl = itemsService.queryItemMainImgById(itemId);
            //1.3 循环保存子订单数据到数据库
            OrderItems subOrderItems = new OrderItems();
            subOrderItems.setItemId(itemId);
            subOrderItems.setItemName(items.getItemName());
            subOrderItems.setItemImg(imgUrl);
            subOrderItems.setBuyCounts(buyCounts);
            subOrderItems.setItemSpecId(itemsSpec.getId());
            subOrderItems.setItemSpecName(itemsSpec.getName());
            subOrderItems.setPrice(itemsSpec.getPriceDiscount());
            subOrderItems.setId(IdWorker.getIdStr());
            subOrderItems.setOrderId(orderId);
            subList.add(subOrderItems);
            //1.4 用户提交订单以后,规格表中需要扣除库存
            itemsService.decreaseItemSpecStock(itemsSpec.getId(), buyCounts);
        }
        newOrder.setTotalAmount(totalAmount);
        newOrder.setRealPayAmount(realPayAmount);
        ordersMapper.insert(newOrder);
        orderItemsMapper.insertBatch(subList);
        //2.保存订单状态表
        OrderStatus waitPayOrderStatus = new OrderStatus();
        waitPayOrderStatus.setOrderId(newOrder.getId());
        waitPayOrderStatus.setOrderStatus(OrderStatusEnum.WAIT_DELIVER.type);
        waitPayOrderStatus.setCreatedTime(new Date());
        orderStatusMapper.insert(waitPayOrderStatus);
        //3. 构建商户订单，用于传给支付中心
        MerchantOrdersVO merchantOrdersVO = new MerchantOrdersVO();
        merchantOrdersVO.setMerchantOrderId(orderId);
        merchantOrdersVO.setMerchantUserId(userId);
        merchantOrdersVO.setAmount(realPayAmount + postAmount);
        merchantOrdersVO.setPayMethod(payMethod);
        OrderVO orderVO = new OrderVO();
        orderVO.setOrderId(orderId);
        orderVO.setMerchantOrdersVO(merchantOrdersVO);
        orderVO.setToBeRemoveShopCartList(toBeRemoveShopCartList);
        return orderVO;
    }

    private ShopCartBO getShopCartBOFromShopCart(List<ShopCartBO> shopCartBOList, String itemId) {
        return shopCartBOList.stream().filter(item -> item.getSpecId().equals(itemId)).findFirst().get();
    }

    /**
     * 修改订单状态
     *
     * @param orderId
     * @param orderStatus
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void updateOrderStatus(String orderId, Integer orderStatus) {
        OrderStatus paidOrderStatus = new OrderStatus();
        paidOrderStatus.setOrderStatus(orderStatus);
        paidOrderStatus.setPayTime(new Date());
        LambdaUpdateWrapper<OrderStatus> condition = Wrappers.<OrderStatus>lambdaUpdate().eq(OrderStatus::getOrderId, orderId);
        orderStatusMapper.update(paidOrderStatus, condition);
    }

    /**
     * 关闭订单
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void closeOrder() {
        LambdaQueryWrapper<OrderStatus> condition = Wrappers.<OrderStatus>lambdaQuery().eq(OrderStatus::getOrderStatus, OrderStatusEnum.WAIT_PAY);
        List<OrderStatus> list = orderStatusMapper.selectList(condition);
        for (OrderStatus os : list) {
            Date createdTime = os.getCreatedTime();
            long days = DateUtil.between(createdTime, new Date(), DateUnit.DAY);
            if (days >= 1) {
                //超过1天关闭
                OrderStatus updateOrderStatus = new OrderStatus();
                updateOrderStatus.setCloseTime(new Date());
                updateOrderStatus.setOrderStatus(OrderStatusEnum.CLOSE.type);
                orderStatusMapper.update(updateOrderStatus,Wrappers.<OrderStatus>lambdaUpdate().eq(OrderStatus::getOrderId,os.getOrderId()));
            }
        }

    }
}
